import json
import allure
from typing import Any
from io import BytesIO
from PIL import Image


def allure_title(title: str, labels: dict = None) -> None:
    """在Allure报告中设置用例标题，并支持添加自定义标签"""
    if not title:
        raise ValueError("Title cannot be empty.")
    allure.dynamic.title(title)

    if labels:
        for key, value in labels.items():
            allure.dynamic.label(key, value)


def allure_step(step_title: str, content: Any, content_type: str = "json", level: str = "INFO") -> None:
    """
    创建Allure步骤并附加内容。

    :param step_title: 步骤及附件名称
    :param content: 附件内容，支持JSON、文本、图片等类型
    :param content_type: 附件类型，支持'json', 'text', 'image', 'html', 'pdf'等
    :param level: 附件日志级别，支持'INFO', 'DEBUG', 'ERROR'等
    """
    if not step_title:
        raise ValueError("Step title cannot be empty.")

    with allure.step(step_title):
        attachment_type = allure.attachment_type.TEXT
        attachment_content = ""

        if content_type == "json":
            try:
                attachment_content = json.dumps(content, ensure_ascii=False, indent=4)
                attachment_type = allure.attachment_type.JSON
            except (TypeError, ValueError) as e:
                attachment_content = f"Failed to convert to JSON: {str(e)}"
        elif content_type == "text":
            attachment_content = str(content)
        elif content_type == "html":
            attachment_content = str(content)
            attachment_type = allure.attachment_type.HTML
        elif content_type == "image":
            attachment_content = content  # Assuming content is binary image data
            attachment_type = allure.attachment_type.PNG
            try:
                # Checking and converting image formats using PIL
                img = Image.open(BytesIO(content))
                img_format = img.format.lower()
                if img_format in ['jpeg', 'jpg']:
                    attachment_type = allure.attachment_type.JPG
                elif img_format in ['gif']:
                    attachment_type = allure.attachment_type.GIF
            except Exception as e:
                attachment_content = f"Failed to load image: {str(e)}"
        elif content_type == "pdf":
            attachment_content = content  # Assuming content is PDF in binary format
            attachment_type = allure.attachment_type.PDF
        else:
            attachment_content = f"Unsupported content type: {content_type}"

        # Attach the content to Allure report with level-based logging
        if level == "ERROR":
            allure.attach(attachment_content, step_title, attachment_type,
                          attachment_level=allure.attachment_level.ATTACHMENT_ERROR)
        elif level == "DEBUG":
            allure.attach(attachment_content, step_title, attachment_type,
                          attachment_level=allure.attachment_level.ATTACHMENT_DEBUG)
        else:
            allure.attach(attachment_content, step_title, attachment_type)
